package com.xiaolin.admin.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.xiaolin.admin.mapper.UserMapper;
import com.xiaolin.admin.model.entity.User;
import com.xiaolin.admin.service.ExcelService;
import com.xiaolin.admin.utils.ComputingTimeUtil;
import com.xiaolin.admin.utils.excel.BigDataExcelStableExportUtil;
import com.xiaolin.admin.utils.excel.NewBigDataExcelExportUtil;
import com.xiaolin.admin.utils.excel.NewExcelExportUtil;
import org.apache.poi.xssf.streaming.SXSSFSheet;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.servlet.http.HttpServletResponse;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * @author xiaolin
 * @description 描述
 * @since 2024/10/23
 */
@Service
public class ExcelServiceImpl implements ExcelService {

    @Autowired
    private UserMapper userMapper;

    private ExecutorService threadPool = Executors.newFixedThreadPool(12);

    @Override
    public void lowExport(HttpServletResponse response) {
        long startTime = ComputingTimeUtil.getStartTime();
        // 数据
        List<User> users = userMapper.selectList(new LambdaQueryWrapper<User>().last("limit 250000"));
        // 导出
        NewExcelExportUtil excelExportUtil = new NewExcelExportUtil();
        excelExportUtil.setTitle("用户导出");
        excelExportUtil.setHeadTitles(new String[][]{{"主键", "账号", "密码", "昵称", "性别", "头像", "手机号", "邮箱", "用户状态", "用户标签列表",
                "删除标记", "创建时间", "修改时间"}});
        excelExportUtil.setHeadKeys(new String[]{"id", "accountNumber", "pwd", "nickname", "gender", "avatar", "phone", "email",
                "state", "userTags", "flag", "createTime", "updateTime"});
//        excelExportUtil.setHeadTitles(new String[][]{{"主键", "账号", "密码", "昵称", "性别", "头像"}});
//        excelExportUtil.setHeadKeys(new String[]{"id", "accountNumber", "pwd", "nickname", "gender", "avatar"});
        List<Map<String, Object>> data = JSON.parseObject(JSON.toJSONString(users), new TypeReference<List<Map<String, Object>>>() {
        });
        System.out.println("拷贝结束。。。");
        excelExportUtil.setData(data);
        long exportStartTime = ComputingTimeUtil.getStartTime();
        excelExportUtil.exportFile(response);
        long endTime = ComputingTimeUtil.getEndTime();
        ComputingTimeUtil.printSeconds("导出耗时：", exportStartTime, endTime);
        ComputingTimeUtil.printSeconds("总耗时：", startTime, endTime);
    }

    @Override
    public void export(HttpServletResponse response) {
        long startTime = ComputingTimeUtil.getStartTime();
        // 数据
        List<User> users = userMapper.selectList(new LambdaQueryWrapper<User>().last("limit 1000000"));
        // 导出
        NewBigDataExcelExportUtil excelExportUtil = new NewBigDataExcelExportUtil();
        excelExportUtil.setTitle("用户导出");
        excelExportUtil.setHeadTitles(new String[][]{{"主键", "账号", "密码", "昵称", "性别", "头像", "手机号", "邮箱", "用户状态", "用户标签列表",
                "删除标记", "创建时间", "修改时间"}});
        excelExportUtil.setHeadKeys(new String[]{"id", "accountNumber", "pwd", "nickname", "gender", "avatar", "phone", "email",
                "state", "userTags", "flag", "createTime", "updateTime"});
//        excelExportUtil.setHeadTitles(new String[][]{{"主键", "账号", "密码", "昵称", "性别", "头像"}});
//        excelExportUtil.setHeadKeys(new String[]{"id", "accountNumber", "pwd", "nickname", "gender", "avatar"});
        List<Map<String, Object>> data = JSON.parseObject(JSON.toJSONString(users), new TypeReference<List<Map<String, Object>>>() {
        });
        System.out.println("拷贝结束。。。");
        excelExportUtil.setData(data);
        long exportStartTime = ComputingTimeUtil.getStartTime();
        excelExportUtil.exportFile(response);
        long endTime = ComputingTimeUtil.getEndTime();
        ComputingTimeUtil.printSeconds("导出耗时：", exportStartTime, endTime);
        ComputingTimeUtil.printSeconds("总耗时：", startTime, endTime);
    }

    /**
     * 稳定导出
     *
     * @param response
     */
    @Override
    public void stableExport(HttpServletResponse response) {
        long startTime = ComputingTimeUtil.getStartTime();
        // 数据
        BigDataExcelStableExportUtil excelExportUtil = new BigDataExcelStableExportUtil();
        excelExportUtil.setTitle("用户导出");
        excelExportUtil.setHeadTitles(new String[][]{{"主键", "账号", "密码", "昵称", "性别", "头像", "手机号", "邮箱", "用户状态", "用户标签列表",
                "删除标记", "创建时间", "修改时间"}});
        excelExportUtil.setHeadKeys(new String[]{"id", "accountNumber", "pwd", "nickname", "gender", "avatar", "phone", "email",
                "state", "userTags", "flag", "createTime", "updateTime"});
        SXSSFWorkbook wb = excelExportUtil.createWb();
        SXSSFSheet sheet = excelExportUtil.creatSheet(wb);
        List<User> users;
        List<Map<String, Object>> data;
        int cursor = 0;
        int initialRow = 2;
        for (int i = 1; i <= 100; i++) {
            users = userMapper.selectList(new LambdaQueryWrapper<User>().gt(User::getId, cursor).last("limit 10000"));
            if (CollectionUtils.isEmpty(users)) {
                break;
            }
            data = JSON.parseObject(JSON.toJSONString(users), new TypeReference<List<Map<String, Object>>>() {
            });
            excelExportUtil.createRows(sheet, data, initialRow);
            cursor = users.get(users.size() - 1).getId();
            initialRow += users.size();
        }
        excelExportUtil.exportFile(wb, response);
        long endTime = ComputingTimeUtil.getEndTime();
        ComputingTimeUtil.printSeconds("总耗时：", startTime, endTime);
    }

    @Override
    public void asyncExport() {
        threadPool.submit(() -> {
            long startTime = ComputingTimeUtil.getStartTime();
            // 数据
            BigDataExcelStableExportUtil excelExportUtil = new BigDataExcelStableExportUtil();
            excelExportUtil.setTitle("用户导出");
            excelExportUtil.setHeadTitles(new String[][]{{"主键", "账号", "密码", "昵称", "性别", "头像", "手机号", "邮箱", "用户状态", "用户标签列表",
                    "删除标记", "创建时间", "修改时间"}});
            excelExportUtil.setHeadKeys(new String[]{"id", "accountNumber", "pwd", "nickname", "gender", "avatar", "phone", "email",
                    "state", "userTags", "flag", "createTime", "updateTime"});
            SXSSFWorkbook wb = excelExportUtil.createWb();
            SXSSFSheet sheet = excelExportUtil.creatSheet(wb);
            List<User> users;
            List<Map<String, Object>> data;
            int cursor = 0;
            int initialRow = 2;
            for (int i = 1; i <= 100; i++) {
                users = userMapper.selectList(new LambdaQueryWrapper<User>().gt(User::getId, cursor).last("limit 10000"));
                if (CollectionUtils.isEmpty(users)) {
                    break;
                }
                data = JSON.parseObject(JSON.toJSONString(users), new TypeReference<List<Map<String, Object>>>() {
                });
                excelExportUtil.createRows(sheet, data, initialRow);
                cursor = users.get(users.size() - 1).getId();
                initialRow += users.size();
            }
            excelExportUtil.exportFile(wb);
            long endTime = ComputingTimeUtil.getEndTime();
            ComputingTimeUtil.printSeconds("总耗时：", startTime, endTime);
        });
    }
}
